#include "ansi.h"
#include "asserts.h"
#include <iostream>
using namespace std;

/** @file UnitTest.cc
 * The implementation of class UnitTest
 *
 * @author R.A.Akkersdijk@saxion.nl
 * @version 1.2	2012/09/24
 */


#include "UnitTest.h"

int  UnitTest::run()
{
	errorCount = 0;

	// Announce this test run
	cout << AC_BLUE "====== Running " << name << AA_RESET << endl;

	std::vector<TestCase>::iterator  i;
	for (i = testcases.begin() ; i != testcases.end() ; ++i)
	{
		TestCase fp = *i;

		// Setup fase (should never fail)
		errorExpected = false;
		try {
			setUp();
		} catch(const assert_error &e) {
			cerr << e.what() << AC_RED "FATAL: Assert error during setUp!\n" AA_RESET << endl;
			++errorCount;
		} catch(const logic_error &e) {
			cerr << e.what() << AC_RED "FATAL: Logic error during setUp!\n" AA_RESET << endl;
			++errorCount;
		}

		// Test fase (by default expect no errors)
		errorExpected = false;
		try {
			(this->*fp)();
			if(errorExpected) {
				cerr << AC_RED "FAIL: EXPECTED AN ERROR BUT THAT DID NOT HAPPEN!" AA_RESET << endl;
				++errorCount;
			}
		} catch(const assert_error &e) {
			if(errorExpected) {		// was expected
				cerr << e.what() << AC_GREEN "GOOD: An expected assert error occurred" AA_RESET << endl;
			} else {			    // was not expected
				cerr << e.what() << AC_RED "FAIL: UNEXPECTED ASSERT ERROR!\n" AA_RESET << endl;
				++errorCount;
			}
		} catch(const logic_error &e) {
			if(errorExpected) {		// was expected
				cerr << e.what() << AC_GREEN "GOOD: An expected logic error occurred" AA_RESET << endl;
			} else {			    // was not expected
				cerr << e.what() << AC_RED "FAIL: UNEXPECTED LOGIC ERROR!\n" AA_RESET << endl;
				++errorCount;
			}
		}

		// Teardown fase (should never fail)
		errorExpected = false;
		try {
			tearDown();
		} catch(const assert_error &e) {
			cerr << e.what() << AC_RED "FATAL: Assert error during tearDown!\n" AA_RESET << endl;
			++errorCount;
		} catch(const logic_error &e) {
			cerr << e.what() << AC_RED "FATAL: Logic error during tearDown!\n" AA_RESET << endl;
			++errorCount;
		}
	}

	// Report final status
	if(errorCount  > 0)
		std::cout << AC_RED "====== Finished " << name << " with " << errorCount << " errors." << AA_RESET << endl << endl;
	else
		std::cout << AC_BLUE "====== Finished " << name << " with " << errorCount << " errors." << AA_RESET << endl << endl;

	return errorCount;
}

// vim:sw=4:ts=4:ai:aw:
